package com.github.ginirohikocha.dbm.activity;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.alibaba.fastjson.JSONObject;
import com.github.ginirohikocha.dbm.Address;
import com.github.ginirohikocha.dbm.R;
import com.github.ginirohikocha.dbm.RequestCode;
import com.github.ginirohikocha.dbm.entity.Offer;
import com.github.ginirohikocha.dbm.util.HttpUtil;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;

public class OfferDetailActivity extends AppCompatActivity {

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA);

    private Uri photoUri;
    private File[] photos = new File[2];

    private LinearLayout offerPhotos;
    private TextView offerTitle, offerDescription, offerAmount, offerPrice, offerStatus;
    private ImageView photo[] = new ImageView[2];
    private Button submit;

    private int currentPhoto;
    private String currentPath;

    private Offer offer;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_offer_detail);

        offerTitle = findViewById(R.id.activity_offer_title);
        offerDescription = findViewById(R.id.activity_offer_description);
        offerAmount = findViewById(R.id.activity_offer_amount);
        offerPrice = findViewById(R.id.activity_offer_price);
        offerStatus = findViewById(R.id.activity_offer_status);
        offerPhotos = findViewById(R.id.activity_offer_photos);
        photo[0] = findViewById(R.id.activity_offer_photo1);
        photo[1] = findViewById(R.id.activity_offer_photo2);
        submit = findViewById(R.id.activity_offer_submit);

        //在被完全覆盖后调用onStop,返回时如果内存不足会导致重新执行onCreate,而非onStart,这时需要获取之前的状态
        if (savedInstanceState != null) {
            String photo1 = savedInstanceState.getString("photo1")
                    , photo2 = savedInstanceState.getString("photo2");

            try {
                if (photo1 != null)
                    photo[0].setImageBitmap(getBitmapFormUri(FileProvider.getUriForFile(OfferDetailActivity.this, "com.github.ginirohikocha.imgs", new File(photo1)), false));
                if (photo2 != null)
                    photo[1].setImageBitmap(getBitmapFormUri(FileProvider.getUriForFile(OfferDetailActivity.this, "com.github.ginirohikocha.imgs", new File(photo2)), false));
            } catch (IOException e) {
                e.printStackTrace();
            }

            currentPhoto = savedInstanceState.getInt("currentPhoto");
            currentPath = savedInstanceState.getString("currentPath");
            photoUri = FileProvider.getUriForFile(OfferDetailActivity.this, "com.github.ginirohikocha.imgs", new File(currentPath));
        }

        getOfferData(getIntent().getIntExtra("id", -1));

        if (savedInstanceState == null) {
            fetchPhoto(getIntent().getIntExtra("id", -1), 0);
            fetchPhoto(getIntent().getIntExtra("id", -1), 1);
        }
    }

    /**
     * 初始化组件
     * **/
    private void initComponent() {
        offerTitle.setText(offer.getOfferTitle());
        offerDescription.setText(offer.getOfferDescription());
        offerAmount.setText(String.format(Locale.CHINESE, "×%d", offer.getOfferAmount()));
        offerPrice.setText(String.format(Locale.CHINESE, "¥%.2f", offer.getOfferPrice().doubleValue()));
        offerStatus.setText(offer.getOfferStatus());

        if (!offer.getOfferStatus().equals("已结束")) {
            photo[0].setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                        takePhoto(0);
                }
            });
            photo[1].setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                        takePhoto(1);
                }
            });
            submit.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    uploadPhotos();
                }
            });
        } else {
            submit.setEnabled(false);
        }

    }
    //获取业务数据
    private void getOfferData(Integer offerId) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("offerId", offerId);

        HttpUtil.sendOkHttpPostRequest(Address.OFFER_QUERY, RequestBody.create(MediaType.parse("text/plain; charset=utf-8"), jsonObject.toJSONString()), new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                Intent result = new Intent();
                result.putExtra("msg", "业务获取失败，请检查网络状态");
                setResult(Activity.RESULT_CANCELED, result);
                finish();
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                String responseBody = response.body().string();
                JSONObject responseJson = JSONObject.parseObject(responseBody);

                try {
                    offer = responseJson.getJSONObject("offer").toJavaObject(Offer.class);
                } catch (NullPointerException e) {
                    Intent result = new Intent();
                    result.putExtra("msg", "数据错误，业务获取失败");
                    setResult(Activity.RESULT_CANCELED, result);
                    finish();
                }
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        initComponent();
                    }
                });
            }
        });
    }
    //上传照片
    private void uploadPhotos() {
        if (photos[0] == null && photos[1] == null)
            finish();

        MultipartBody.Builder multipartBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("offer", JSONObject.toJSONString(offer));

        if (photos[0] != null)
            multipartBody.addFormDataPart("photo1", photos[0].getName(), RequestBody.create(MediaType.parse("image/jpg"), photos[0]));
        if (photos[1] != null)
            multipartBody.addFormDataPart("photo2", photos[1].getName(), RequestBody.create(MediaType.parse("image/jpg"), photos[1]));

        HttpUtil.sendOkHttpPostRequest(Address.OFFER_UPLOAD_PHOTO, multipartBody.build(), new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {

            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                String responseBody = response.body().string();

                final JSONObject jsonObject = JSONObject.parseObject(responseBody);
                try {
                    if (jsonObject.getBoolean("succ")) {
                        setResult(RESULT_OK);
                        finish();
                    } else {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(OfferDetailActivity.this, jsonObject.getString("msg"), Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                } catch (NullPointerException e) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(OfferDetailActivity.this, "系统错误", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            }
        });
    }
    //下载照片
    private void fetchPhoto(Integer offerId, final Integer type) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("offerId", offerId);
        jsonObject.put("type", type);

        HttpUtil.sendOkHttpPostRequest(Address.OFFER_FETCH_PHOTO, RequestBody.create(MediaType.parse("text/plain; charset=utf-8"), jsonObject.toJSONString()), new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                //获取响应体
                ResponseBody body = response.body();
                if (body == null)
                    return;
                //获取流
                InputStream in = body.byteStream();
                //转化为bitmap
                final Bitmap bitmap = BitmapFactory.decodeStream(in);
                if (bitmap != null)
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (type == 0)
                                photo[0].setImageBitmap(bitmap);
                            if (type == 1)
                                photo[1].setImageBitmap(bitmap);
                        }
                    });
            }
        });
    }
    //拍照返回结果
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch (requestCode) {
            case RequestCode.REQUEST_IMG_CAPTURE:
                if (resultCode == RESULT_OK) {
                    if(data !=null){ //可能尚未指定intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
                        //返回有缩略图
                        if(data.hasExtra("data")){
                            Bitmap thumbnail = data.getParcelableExtra("data");
                            //得到bitmap后的操作
                            loadPhoto(thumbnail);
                        }
                    }else{
                        //由于指定了目标uri，存储在目标uri，intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
                        // 通过目标uri，找到图片
                        // 对图片的缩放处理
                        // 操作
                        try {
                            Bitmap bm = getBitmapFormUri(photoUri, true);
                            loadPhoto(bm);
                        } catch (IOException | NullPointerException e) {
                            Toast.makeText(OfferDetailActivity.this, "拍照失败，请重试", Toast.LENGTH_SHORT).show();
                        }
                    }
                }
        }
    }

    private void takePhoto(int currentPhoto) {
        this.currentPhoto = currentPhoto;
        //创建存储照片的文件
        String path = getFilesDir() + File.separator + "images" + File.separator;
        File file = new File(path, "DBM"+sdf.format(new Date())+".jpg");
        if(!file.getParentFile().exists())
            file.getParentFile().mkdirs();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //Android 7.0及以上获取文件 Uri
            photoUri = FileProvider.getUriForFile(OfferDetailActivity.this, "com.github.ginirohikocha.imgs", file);
        } else {
            //获取文件Uri
            photoUri = Uri.fromFile(file);
        }
        currentPath = file.getPath();

        //调取系统拍照
        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
        intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
        startActivityForResult(intent, RequestCode.REQUEST_IMG_CAPTURE);
    }

    private void loadPhoto(Bitmap bitmap) throws NullPointerException{
        photos[currentPhoto] = saveBitmapFile(bitmap, currentPath);
        photo[currentPhoto].setImageBitmap(bitmap);
        Toast.makeText(OfferDetailActivity.this, "操作成功", Toast.LENGTH_SHORT).show();
    }

    //获取本地图片
    public Bitmap getBitmapFormUri(Uri uri, boolean needCompress) throws IOException, NullPointerException {
        InputStream input = getContentResolver().openInputStream(uri);
        //这一段代码是不加载文件到内存中也得到bitmap的真是宽高，主要是设置inJustDecodeBounds为true
        BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
        onlyBoundsOptions.inJustDecodeBounds = true;//不加载到内存
        onlyBoundsOptions.inDither = true;//optional
        onlyBoundsOptions.inPreferredConfig = Bitmap.Config.RGB_565;//optional
        BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
        input.close();
        int originalWidth = onlyBoundsOptions.outWidth;
        int originalHeight = onlyBoundsOptions.outHeight;
        if ((originalWidth == -1) || (originalHeight == -1))
            return null;

        //图片分辨率
        float hh = 1600f;//设置高度
        float ww = 900f;//设置宽度
        //缩放比，由于是固定比例缩放，只用高或者宽其中一个数据进行计算即可
        int be = 1;//be=1表示不缩放
        if (originalWidth > originalHeight && originalWidth > ww) {//如果宽度大的话根据宽度固定大小缩放
            be = (int) (originalWidth / ww);
        } else if (originalWidth < originalHeight && originalHeight > hh) {//如果高度高的话根据宽度固定大小缩放
            be = (int) (originalHeight / hh);
        }
        if (be <= 0)
            be = 1;
        //比例压缩
        BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
        bitmapOptions.inSampleSize = be;//设置缩放比例
        bitmapOptions.inDither = true;
        bitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
        input = getContentResolver().openInputStream(uri);
        Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
        input.close();

        if (needCompress)
            return compressImage(bitmap);//再进行质量压缩
        else
            return bitmap;
    }
    //压缩图片
    public Bitmap compressImage(Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法，这里100表示不压缩，把压缩后的数据存放到baos中
        int options = 100;
        while (baos.toByteArray().length / 1024 > 100) {  //循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset();//重置baos即清空baos
            //第一个参数 ：图片格式 ，第二个参数： 图片质量，100为最高，0为最差  ，第三个参数：保存压缩后的数据的流
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options，把压缩后的数据存放到baos中
            options -= 10;//每次都减少10
            if (options<=0)
                break;
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片

        return bitmap;
    }
    //保存bitmap为文件
    public File saveBitmapFile(Bitmap bitmap, String path) {
        File file = new File(path);//将要保存图片的路径
        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
            bos.flush();
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    private void clearStorage() {
        String path = getFilesDir() + File.separator + "images" + File.separator;
        File file = new File(path);
        File[] files = file.listFiles();
        if (files.length != 0) {
            for (File f:files) {
                f.delete();
            }
        }
    }

    //调用onStop时遇见内存暂时被剥夺时的状态存储
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putString("currentPath", currentPath);
        outState.putInt("currentPhoto", currentPhoto);
        if (photos[0] != null)
            outState.putString("photo1", photos[0].getPath());
        if (photos[1] != null)
            outState.putString("photo2", photos[1].getPath());
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onDestroy() {
        photo[0].setImageBitmap(null);
        photo[1].setImageBitmap(null);
        clearStorage();
        super.onDestroy();
    }
}
